#include "core/project/project_manager.h"
#include <QDir>
#include <QFile>
#include <QJsonDocument>
#include <QJsonArray>
#include <QMessageBox>

ProjectManager::ProjectManager(QObject *parent)
    : QObject(parent) {
    connect(&m_fileWatcher, &QFileSystemWatcher::fileChanged,
            this, &ProjectManager::fileChanged);
}

bool ProjectManager::createProject(const QString &path, const QString &name, const QString &templateName) {
    QDir dir(path);
    if (!dir.exists()) {
        if (!dir.mkpath(".")) {
            return false;
        }
    }
    
    QString projectDir = dir.absoluteFilePath(name);
    if (QDir(projectDir).exists()) {
        return false;
    }
    
    if (!dir.mkdir(name)) {
        return false;
    }
    
    m_projectPath = QDir(projectDir).absoluteFilePath("project.cforge");
    
    // 创建基本项目结构
    QDir(projectDir).mkdir("src");
    QDir(projectDir).mkdir("include");
    QDir(projectDir).mkdir("build");
    
    // 初始化项目配置
    m_projectConfig = QJsonObject();
    m_projectConfig["name"] = name;
    m_projectConfig["type"] = templateName.isEmpty() ? "console" : templateName;
    m_projectConfig["files"] = QJsonArray();
    
    // 保存项目文件
    if (!saveProject()) {
        QDir(projectDir).removeRecursively();
        return false;
    }
    
    emit projectOpened(name);
    return true;
}

bool ProjectManager::openProject(const QString &path) {
    QFileInfo info(path);
    if (!info.exists() || info.suffix() != "cforge") {
        return false;
    }
    
    m_projectPath = path;
    loadProject();
    
    emit projectOpened(projectName());
    return true;
}

bool ProjectManager::saveProject() {
    if (m_projectPath.isEmpty()) {
        return false;
    }
    
    QFile file(m_projectPath);
    if (!file.open(QIODevice::WriteOnly)) {
        return false;
    }
    
    QJsonDocument doc(m_projectConfig);
    file.write(doc.toJson());
    file.close();
    
    return true;
}

bool ProjectManager::closeProject() {
    if (!isProjectOpen()) {
        return false;
    }
    
    m_projectPath.clear();
    m_projectConfig = QJsonObject();
    m_fileWatcher.removePaths(m_fileWatcher.files());
    
    emit projectClosed();
    return true;
}

QString ProjectManager::projectName() const {
    return m_projectConfig["name"].toString();
}

QString ProjectManager::projectPath() const {
    return QFileInfo(m_projectPath).absolutePath();
}

QStringList ProjectManager::sourceFiles() const {
    QStringList files;
    QJsonArray fileArray = m_projectConfig["files"].toArray();
    for (const QJsonValue &value : fileArray) {
        files.append(value.toString());
    }
    return files;
}

void ProjectManager::addFile(const QString &filePath) {
    QJsonArray fileArray = m_projectConfig["files"].toArray();
    
    QString relativePath = QDir(projectPath()).relativeFilePath(filePath);
    if (!fileArray.contains(relativePath)) {
        fileArray.append(relativePath);
        m_projectConfig["files"] = fileArray;
        saveProject();
        
        m_fileWatcher.addPath(filePath);
        emit fileAdded(filePath);
    }
}

void ProjectManager::removeFile(const QString &filePath) {
    QJsonArray fileArray = m_projectConfig["files"].toArray();
    
    QString relativePath = QDir(projectPath()).relativeFilePath(filePath);
    for (int i = 0; i < fileArray.size(); ++i) {
        if (fileArray[i].toString() == relativePath) {
            fileArray.removeAt(i);
            m_projectConfig["files"] = fileArray;
            saveProject();
            
            m_fileWatcher.removePath(filePath);
            emit fileRemoved(filePath);
            break;
        }
    }
}

QJsonObject ProjectManager::projectConfig() const {
    return m_projectConfig;
}

void ProjectManager::setProjectConfig(const QJsonObject &config) {
    m_projectConfig = config;
    saveProject();
}

bool ProjectManager::isProjectOpen() const {
    return !m_projectPath.isEmpty();
}

void ProjectManager::loadProject() {
    QFile file(m_projectPath);
    if (!file.open(QIODevice::ReadOnly)) {
        return;
    }
    
    QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
    m_projectConfig = doc.object();
    
    // 设置文件监视器
    setupFileWatcher();
}

void ProjectManager::setupFileWatcher() {
    m_fileWatcher.removePaths(m_fileWatcher.files());
    
    QStringList files = sourceFiles();
    for (const QString &file : files) {
        QString absPath = QDir(projectPath()).absoluteFilePath(file);
        m_fileWatcher.addPath(absPath);
    }
}